import PubSub.*;

import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

import java.util.*;

public final class Server {
	
	public static void main(String[] args) {
		String name = "Broker";
		String host = "localhost";
		String port = "1050";
		ORB orb;
		POA rootpoa;
		NamingContextExt rootContext;
		NamingContextExt topicContext;
		NamingContextExt clientContext;
		BrokerImpl brokerImpl;
		
		try {
			if(args.length==2) {
				host = args[0];
				port = args[1];
			} else if(args.length>2 || args.length==1) {
				System.out.println(
					"ERROR: Invalid parameters. Correct call is:"+
					"\n\tjava PubSubClient host port\n"+
					"Default settings will be used"
				);
			}
			// create and initialize the ORB
			Properties props = new Properties();
			props.put("org.omg.CORBA.ORBInitialHost", host);
			props.put("org.omg.CORBA.ORBInitialPort", port);
			orb = ORB.init(new String[0], props);

			// get reference to rootpoa & activate the POAManager
			rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
			rootpoa.the_POAManager().activate();
			
			// get the root naming context
			rootContext = NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService"));
			System.out.println("Resolved initial naming context");
			
			// creating Topic subcontext
			try {
				topicContext = NamingContextExtHelper.narrow(rootContext.bind_new_context(rootContext.to_name("Topic")));
				System.out.println("Added subcontext Topic under initial naming context");
			} catch(AlreadyBound e) {
				topicContext = NamingContextExtHelper.narrow(rootContext.resolve(rootContext.to_name("Topic")));
				System.out.println("Subcontext Topic already bound");
			}
			
			// creating Client subcontext
			try {
				clientContext = NamingContextExtHelper.narrow(rootContext.bind_new_context(rootContext.to_name("Client")));
				System.out.println("Added subcontext Client under initial naming context");
			} catch(AlreadyBound e) {
				clientContext = NamingContextExtHelper.narrow(rootContext.resolve(rootContext.to_name("Client")));
				System.out.println("Subcontext Client already bound");
			}
			
			// create servant and register it with the ORB
			brokerImpl = new BrokerImpl(orb);
			// get object reference from the servant
			org.omg.CORBA.Object brokerRef = rootpoa.servant_to_reference(brokerImpl);
			Broker broker = BrokerHelper.narrow(brokerRef);

			// bind the Broker Reference in Naming
			NameComponent[] brokerPath = rootContext.to_name(name);
			rootContext.rebind(brokerPath, broker);
			System.out.println("Broker rebind successful");
			
			System.out.println("Broker ready and waiting...\n");

			// wait for invocations from clients
			orb.run();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// likely unreachable code
		System.out.println("Broker shutting down");
		System.exit(0);
	}
}